package titt.service.proxy;

import titt.TITTValues;
import titt.head.HeadFactory;
import titt.head.Header;
import titt.head.request.MethodHead;
import titt.head.request.Request;
import titt.head.response.ResponseHead;
import titt.io.IOFactory;
import titt.io.encoding.EncodingFacade;
import titt.io.reader.ResponseReader;
import titt.io.socket.TITTSocket;
import titt.io.writer.POSTWriter;
import titt.key.KeyFactory;
import titt.key.TITTKey;
import titt.type.Type;
import titt.type.TypedObject;
import titt.util.ArrayUtil;
import titt.util.Converter;

public class TITTRequester {

	private final TITTKey key;
	private final EncodingFacade ef = IOFactory.createEncodingFacade();
	private final Converter<Object, TypedObject> toTyped = new Converter<Object, TypedObject>() {
		@Override
		public TypedObject convert(Object o) {
			return new TypedObject(new Type(o), o);
		}
	};

	public TITTRequester(String... tokens) {
		this.key = KeyFactory.createKey(tokens);
	}
	
	public void sendRequest(TITTSocket ts, String name) throws Exception {
		sendRequest(ts, name, new Object[0]);
	}

	public void sendRequest(TITTSocket ts, String name, Object... args) throws Exception {
		sendRequest(ts, name, ArrayUtil.convertTo(args, new TypedObject[args.length], toTyped));
	}	

	public void sendRequest(TITTSocket ts, String name, TypedObject... args) throws Exception {

		try {

			MethodHead m = new MethodHead(name, new TypedObject[0], new TypedObject[0], new Request(args.length == 0? TITTValues.GET : TITTValues.POST, key.asKeyString(), HeadFactory.createHead(new Header("Accept", "titt"))));

			if(args.length > 0) {
				POSTWriter pw = new POSTWriter(ts, ef, m);
				pw.writeValues(args);
			}
			else ts.getHeadWriter().writeHead(m);


		}
		catch(Exception e) {

			ts.close();
			throw e;

		}
	}

	public TypedObject readResponse(TITTSocket ts) throws Exception {
		return readResponse(ts, null);
	}
	
	public TypedObject readResponse(TITTSocket ts, Type ret) throws Exception {
		ResponseHead resp = new ResponseHead(ts.getHeadReader().readHead());

		ResponseReader rr = new ResponseReader(ts, ef, resp, ret);

		return rr.readValues()[0];

	}
}
